package fr.utbm.tx52.stamp.logic;

import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.net.Uri;
import android.provider.ContactsContract;
import android.provider.ContactsContract.Contacts;
import fr.utbm.tx52.stamp.R;
import java.io.InputStream;

/**
 * Classe publique qui repr�sente un contact manipul� par l'application et qui
 * impl�mente l'interface Comparable
 *
 * @author Xavier MICHEL (xavier.michel@utbm.fr) David LACHICHE
 * (david.lachiche@utbm.fr)
 */
public class Contact implements Comparable<Contact>
{

	/**
	 * Identifiant android du contact
	 */
	private String id;
	/**
	 * Nom du contact
	 */
	private String name;
	/**
	 * Num�ro de t�l�phone du contact
	 */
	private String phoneNumber;
	/**
	 * Image du contact
	 */
	private Bitmap bitmap;

	/**
	 * Constructeur par d�faut qui permet de construire un contact
	 *
	 * @param _name Nom du contact
	 * @param _img Image du contact
	 * @param _id Identifiant du contact
	 * @param _phoneNumber Num�ro de t�l�phone du contact
	 */
	public Contact(String _name, Bitmap _img, String _id, String _phoneNumber)
	{
		this.name = _name;
		this.bitmap = _img;
		this.id = _id;
		this.phoneNumber = _phoneNumber;
	}

	/**
	 * Obtient l'identifiant du contact
	 *
	 * @return L'ID du contact
	 */
	public String getID()
	{
		return id;
	}

	/**
	 * Obtient le nom du contact
	 *
	 * @return Le nom du contact
	 */
	public String getName()
	{
		return name;
	}

	/**
	 * Obtient l'image du contact
	 *
	 * @return L'image du contact
	 */
	public Bitmap getBitmap()
	{
		return bitmap;
	}

	/**
	 * Obtient le num�ro de t�l�phone du contact
	 *
	 * @return Le num�ro de t�l�phone du contact
	 */
	public String getPhoneNumber()
	{
		return phoneNumber;
	}

	/**
	 * Compare deux contacts, sur leur nom dans le cas pr�sent
	 *
	 * @return
	 * @see Comparable
	 */
	public int compareTo(Contact _another)
	{
		return name.compareTo(_another.name);
	}

	/**
	 * Obtient le nom d'un contact � partir de son identifiant
	 *
	 * @param _activity L'activit� sur laquelle porte l'action
	 * @param _id L'identifiant du contact
	 * @return Le nom du contact
	 */
	public static String getContactNameFromID(final Activity _activity, final Integer _id)
	{

		Uri dataUri = ContactsContract.Data.CONTENT_URI;

		String[] projection = new String[]
		{
			ContactsContract.Contacts.DISPLAY_NAME,
			ContactsContract.CommonDataKinds.Phone.CONTACT_ID
		};

		Cursor c = _activity.managedQuery(
			dataUri,
			projection,
			ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=" + _id.toString(),
			null, null);

		c.moveToFirst();
		return c.getString(0);
	}

	/**
	 * Obtient l'image d'un contact � partir de son ID
	 *
	 * @param context Le contexte de l'application
	 * @param contactId L'identifiant du contact
	 * @return L'image du contact
	 */
	public static Bitmap loadContactPhoto(Context _context, Long _contactId)
	{
		Uri contactPhotoUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, _contactId);
		ContentResolver cr = _context.getContentResolver();
		InputStream input = ContactsContract.Contacts.openContactPhotoInputStream(cr, contactPhotoUri);
		Bitmap b = BitmapFactory.decodeStream(input);
		if (b == null)
		{
			// Icone des contacts par d�faut
			return ((BitmapDrawable) _context.getResources().getDrawable(R.drawable.pic_contact_badge)).getBitmap();
		}
		else
		{
			return b;
		}
	}

	/**
	 * Renvoi une instance de contact �partir de l'ID pass� en param�tre
	 *
	 * @param context Le contexte de l'application
	 * @param id L'identifiant du contact
	 * @return L'instance d'un contact
	 */
	public static Contact getContactFromID(Context _context, String _id)
	{
		// R�cup�ration du num�ro de t�l�phone
		String[] projectionPhone = new String[]
		{
			ContactsContract.CommonDataKinds.Phone.NUMBER
		};

		Cursor phones = _context.getContentResolver().query(
			ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
			projectionPhone,
			ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + _id,
			null,
			null);

		phones.moveToNext();
		String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
		phones.close();

		// Autres donn�es du contact
		String[] projection = new String[]
		{
			ContactsContract.Contacts.DISPLAY_NAME,
			ContactsContract.CommonDataKinds.Phone.CONTACT_ID
		};

		Cursor c = _context.getContentResolver().query(
			ContactsContract.Data.CONTENT_URI,
			projection,
			ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=" + _id,
			null, null);

		c.moveToFirst();

		String name = c.getString(0);

		Bitmap photo = Contact.loadContactPhoto(_context, Long.decode(_id.toString()));

		return new Contact(
			name,
			photo,
			_id.toString(),
			phoneNumber);
	}

	/**
	 * Envoi une instance de contact �partir du num�ro de t�l�phone donn�
	 *
	 * @param c L'activit� qui veut le contact
	 *
	 * @param phone Le num�ro de t�l�phone du contact
	 *
	 * @return Le contact dont le num�ro est donn�
	 */
	public static Contact getContactsByPhone(Context context, String phone)
	{

		String[] projection = new String[]
		{
			ContactsContract.CommonDataKinds.Phone.CONTACT_ID
		};

		Cursor phones = context.getContentResolver().query(
			ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
			projection,
			ContactsContract.CommonDataKinds.Phone.NUMBER + "= '" + phone + "'",
			null,
			null);

		phones.moveToFirst();

		return getContactFromID(context, phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID)));
	}

	/**
	 * Renvoi un contact en fonction de l'intent donn�e (qui est l'intent du
	 * listPicker en cas d'ajout de contact)
	 *
	 * @param intent L'intent d'ajout de contact
	 *
	 * @return	Le contact qui correspond
	 */
	public static Contact getContactFromUri(Context context, Uri uri)
	{
		return Contact.getContactFromID(context, "" + ContentUris.parseId(uri));
	}

	public Uri getUri()
	{
		return ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, Long.parseLong(id));
	}

	public boolean matchFilter(String filter)
	{
		if ("".equals(filter) || filter == null)
		{
			return true;
		}
		else if (name == null || phoneNumber == null)
		{
			return false;
		}
		else
		{
			return (name.toLowerCase().contains(filter.toLowerCase()) || phoneNumber.toLowerCase().contains(filter.toLowerCase()));
		}
	}
}